package com.juyu.miliao.api.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.juyu.miliao.api.cache.GradeCache;
import com.juyu.miliao.api.constant.AnswerStatusRedis;
import com.juyu.miliao.api.constant.UserLineStatusConstant;
import com.juyu.miliao.api.dao.mysql.*;
import com.juyu.miliao.api.dao.redis.*;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.*;
import com.juyu.miliao.api.domain.dto.IntegralLevelAndTitleDTO;
import com.juyu.miliao.api.domain.dto.LocationDTO;
import com.juyu.miliao.api.domain.dto.UserAssessLabelDTO;
import com.juyu.miliao.api.domain.dto.UserInfoDistanceDTO;
import com.juyu.miliao.api.domain.vo.HostUserLevelVo;
import com.juyu.miliao.api.domain.vo.UserPowerVo;
import com.juyu.miliao.api.domain.vo.UserStatusVO;
import com.juyu.miliao.api.util.*;
import com.juyu.miliao.common.constant.LocationConstant;
import com.juyu.miliao.common.domain.CommonHead;
import com.juyu.miliao.common.domain.GaodeConfig;
import com.juyu.miliao.common.domain.OpenApiStatus;
import com.juyu.miliao.common.domain.vo.HostRecentDevelopmentsPhotoVO;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import com.juyu.miliao.common.exception.IllegalParamException;
import com.juyu.miliao.common.netease.NetEaseCloudUserService;
import com.juyu.miliao.common.util.*;
import com.juyu.miliao.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.juyu.miliao.common.msg.CommonErrorMsgs.RESOURCE_NOT_FOUND;
import static com.juyu.miliao.common.msg.CommonErrorMsgs.UPDATE_USER_NICENAME;
import static com.juyu.miliao.common.msg.CommonErrorMsgs.UPDATE_VIP_USER_NICENAME;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;

@Service
public class UserInfoService {
    private final Logger logger = LoggerFactory.getLogger(UserInfoService.class);
    @Resource
    private UserInfoDao userInfoDao;
    @Resource
    private VisitorRedisDao visitorRedisDao;
    @Resource
    private FollowRedisDao followRedisDao;
    @Resource
    private UserCountDao userCountDao;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private LineTimeRedisDao lineTimeRedisDao;
    @Resource
    private UserWalletService userWalletService;
    @Resource
    private UserLoginDao userLoginDao;
    @Resource
    private UserCallRedisDao userCallRedisDao;
    @Resource
    private LabelService labelService;
    @Resource
    private UserVipService userVipService;
    @Resource
    private BillDetailService billDetailService;
    @Resource
    private GiftSpendService giftSpendService;
    @Resource
    private UserRedisDao userRedisDao;
    @Resource
    private UserCoverUrlDao userCoverUrlDao;
    @Resource
    private OpenApiService openApiService;
    @Resource
    private UserInfoCache userInfoCache;
    @Resource
    private AppKeyService appkeyService;
    @Resource
    private EnergyLevelService energyLevelService;
    @Resource
    private EnergyLevelDao energyLevelDao;
    @Resource
    private IntegralLevelInfoService integralLevelInfoService;
    @Resource
    private SystemMessageUtil systemMessageUtil;

    @Resource
    private HostRealTimeLocationRedisDao hostRealTimeLocationRedisDao;

    @Resource
    private HostRecentDevelopmentsRedisDao hostRecentDevelopmentsRedisDao;


    private static final long robotSendMessageUserId = 12890000;

    public User getUserInfoById(long id, long tokenUserId) {
        User user = userInfoDao.getUserInfoById(id);
        if (user == null)
            throw new IllegalParamException("用户不存在");
        //黑白版需求
        if (AuditAccountUtil.isAuditAccount(user.getUserId())) {
            user.setVisitorSum(0);
        }
        if (id != tokenUserId) {
            // 判断登录用户是否以前访问过该用户
            Optional<Long> findCountVisitor = visitorRedisDao.findCountVisitor(tokenUserId, id);
            if (!findCountVisitor.isPresent()) {
                // 否：用户统计表访客人数+1
                userCountDao.addVisitorSum(id);
                user.setVisitorSum(user.getVisitorSum() + 1);
            }
            visitorRedisDao.insertOrUpdateVisitor(new Visitor(tokenUserId, id));
            Optional<Long> countFollow = followRedisDao.countFollow(tokenUserId, id);
            if (countFollow.isPresent())
                user.setIsFollow(1);
            else
                user.setIsFollow(2);
        }
        // 魅力等级
        List<Grade> gradeList = GradeCache.INSTANCE.getGradeList(1);
        user.setmGrade(GradeUtil.getGradeCount(gradeList, user.getmGradeSum()));
        user.setmNextGradeSum(GradeUtil.getGradeNextSum(gradeList, user.getmGradeSum()));
        // 土豪等级
        gradeList = GradeCache.INSTANCE.getGradeList(2);
        user.setvGrade(GradeUtil.getGradeCount(gradeList, user.getvGradeSum()));
        user.setvNextGradeSum(GradeUtil.getGradeNextSum(gradeList, user.getvGradeSum()));
        // 生日转换成年龄
        if (user.getBirthday() != null) {
            user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
            user.setBirthdayInstant(user.getBirthday().toString());
        }
        double callSum = user.getCallSuccessSum() + user.getCallFailSum();
        if (callSum != 0) {
            double rate = (Double.parseDouble(user.getCallSuccessSum() + "") / callSum);
            user.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
        } else {
            user.setCallRate("100%");
        }
        //用户增加标签
        List<Label> labels = labelService.getLabelForMeLabel(user.getUserId());
//        if(labels.size() > 3){
//            labels = new ArrayList<>(labels.subList(0,3));
//        }
        user.setLabelList(labels);

        UserWallet userWallet = userWalletService.getUserWalletById(user.getUserId());
        user.setUserWallet(userWallet);
        if (user.getIsVip() == 1 || user.getIsSvip()==1 || user.getIsPlatinumVip()==1) {
            UserVip userVip = userVipService.getUserVipById(user.getUserId());
            if (userVip != null) {
                user.setVipDate(userVip.getVipDate());
            }
        }
        if (user.getCallTimeSum() != null
                && !user.getCallTimeSum().equals("0")
                && !user.getCallTimeSum().equals("")) {
            user.setCallTimeSum(CallTimeUtil.secondToTime(Long.parseLong(user.getCallTimeSum())));
        } else {
            user.setCallTimeSum("00:00:00");
        }
        // 判断用户是否在线
        if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
            user.setIsLine(1);
        //如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
        if (user.getIsHost() == 1 && userCallRedisDao.findHostCall(user.getUserId() + ""))
            user.setIsLine(2);
        // 判断用户是否勿扰
        if (user.getIsVideo() == 2)
            user.setIsLine(3);
        //判断用户是否被封停
        if (user.getEnable() == 2) {
            user.setIsLine(4);
        }
        //风控
//        user.setVoiceSignature("");
//        user.setVoiceSignatureTime(0);
        if (user.getIsHost() == 1 || user.getIsVip() == 1 || user.getIsSvip()==1 || user.getIsPlatinumVip()==1) {
            user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
        }
        if(user.getIsHost() == 1 && user.getIsLine()==0){
            Double singOutDateTime = lineTimeRedisDao.getHostUserSingOutDateTimeByHost(user.getUserId());
            user.setSingOutDateTime(singOutDateTime);
            user.setSingOutDateTimeStr(DateUtil.getSingOutDateTime(singOutDateTime.longValue()));
        }
        return user;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public int updateUserInfo(User entity) {
        User userInfoById = userInfoDao.getUserInfoById(entity.getUserId());
        if (!CommonUtil.isEmptyString(entity.getVoiceSignature())) {
            if(userInfoById!=null){
                if (userInfoById.getIsHost() != 1) {
                    throw new ConsumeRuntimeException("您还不是主播，无法添加语音介绍");
                }
            }
        }
        // logger.info("user========="+entity);
        if (entity.getVoiceSignature() != null) {
            IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(userInfoById.getIntegralSum());
            if (userIntegralLevel.getIsModifyVoiceIntroduction() == 0) {
                throw new ConsumeRuntimeException("修改语音介绍功能未开通");
            }
        }
        int result = 0;
        if (entity.getNickName() != null) {
            updateUserNameByUserName(entity.getUserId(), entity.getNickName());
        } else {
            result = userInfoDao.updateUserInfo(entity);
        }


        //更新成功后维护状态
        if (result == 1) {
            //删出在线主播列表用户
            if (entity.getIsVideo() == 2) {
                lineTimeRedisDao.deleteHostLine(entity.getUserId() + "");
                lineTimeRedisDao.deleteLine(entity.getUserId() + "");
                lineTimeRedisDao.deleteOnLineUserBySex(entity.getSex(), entity.getUserId() + "");
            }
            if (entity.getSex() != 0)
                lineTimeRedisDao.deleteOnLineUserBySex(entity.getSex(), entity.getUserId() + "");
            Long userId = entity.getUserId();
            // 修改用户后,更新首页缓存
//            rabbitDao.updateUserInfo(entity);
            // 如果改了生日,同步到user_login
            if (entity.getBirthday() != null) {
                int age = SumAgeUtil.getAgeByBirth(entity.getBirthday());
                userLoginDao.updateUserLoginAge(age, userId);
            }
            //维护redis可聊状态
            User statusUser = userInfoDao.getUserStatus(userId);
            if (statusUser.getIsVideo() == 2) {
                //勿扰
                stringRedisTemplate.opsForValue().set(AnswerStatusRedis.ANSWER_STATUS + entity.getUserId(), AnswerStatusRedis.ANSWER_FALSE);
            } else {
                stringRedisTemplate.opsForValue().set(AnswerStatusRedis.ANSWER_STATUS + entity.getUserId(), AnswerStatusRedis.ANSWER_TRUE);
            }
            //更新成功后 redis 中存储 修改 NickName Signature Icon 字段 用户的id
            User user = userInfoDao.getUserById(entity.getUserId());
            if (user.getIsHost() != 1) {
                if (entity.getNickName() != null) {
                    userRedisDao.userInfoCheckNicName(entity.getUserId());
                }
                if (entity.getSignature() != null) {
                    userRedisDao.userInfoCheckSignature(entity.getUserId());
                }
                if (entity.getIcon() != null) {
                    userRedisDao.userInfoCheckIcon(entity.getUserId());
                }
            } else {
                if (entity.getNickName() != null) {
                    userRedisDao.userInfoCheckNicNameForHost(entity.getUserId(), entity.getNickName());
                }
                if (entity.getSignature() != null) {
                    userRedisDao.userInfoCheckSignatureForHost(entity.getUserId());
                }
                if (entity.getIcon() != null) {
                    userRedisDao.userInfoCheckIconForHost(entity.getUserId(), entity.getIcon());
                }
                if (entity.getVoiceSignature() != null) {
                    Boolean ishaveVoice = userRedisDao.getUserInfoCheckVoice(entity.getUserId());
                    if (ishaveVoice) {
                        userRedisDao.delUserInfoCheckVoice(entity.getUserId());
                        userRedisDao.userInfoCheckVoice(entity.getUserId(), entity.getVoiceSignature(), String.valueOf(entity.getVoiceSignatureTime()));
                    } else {
                        userRedisDao.userInfoCheckVoice(entity.getUserId(), entity.getVoiceSignature(), String.valueOf(entity.getVoiceSignatureTime()));
                    }
                }
            }

        }

        return result;
    }

    /**
     * 用户修改昵称成功发送给云信
     *
     * @param userId
     * @param niceName
     */
    public void sendYunXinUpdateNiceName(long userId, String niceName) {
        logger.info("用户修改操作:参数:userId={},nickName={}", userId, niceName);
        try {
            if (niceName != null) {
                String createLogInfo = NetEaseCloudUserService.updateUserInfo(userId, niceName,
                        "");
                if (!createLogInfo.substring(createLogInfo.indexOf("code") + 6, createLogInfo.indexOf("code") + 9)
                        .equals("200")) {
                    logger.error("更新用户基本信息IM失败:系统错误信息:createLogInfo={},参数:userId={},nickName={},icon={}", createLogInfo, userId
                            , niceName, "");
                }
                if (!CommonUtil.isEmptyString(niceName)) {
                    userInfoDao.updateUserLoginNickName(userId, niceName);
                }
            }
        } catch (Exception e) {
            logger.error("更新用户基本信息IM错误:参数-" + userId + niceName, e);
        }
    }

    public void updateCleanUserInfo(User user) {
        userInfoDao.updateCleanUserInfo(user.getUserId());
    }

    public List<User> getVisitorListByUserId(long id, int page, int pageSize) {
        if (AuditAccountUtil.isAuditAccount(id)) {
            return new ArrayList<>();
        }
        int startNum = PageUtil.getOffset(page, pageSize);
        List<Visitor> visitors = visitorRedisDao.getVisitorIdsByUserId(id, startNum, pageSize);
        Map<Long, Visitor> visitorMap = visitors.stream()
                .collect(Collectors.toMap(Visitor::getVisitorUserId, Function.identity()));
        List<User> userList = userInfoDao.getVisitorListByUserId(visitorMap.keySet());
        // 封装时间加排序
        return userList.stream().map(user -> {
            user.setVisitorTime(visitorMap.get(user.getUserId()).getVisitorTime());
            // 生日转换成年龄
            if (user.getBirthday() != null) {
                user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
                user.setBirthdayInstant(user.getBirthday().toString());
            }
            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
                user.setIsLine(1);
            //如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
            if (user.getIsHost() == 1 && userCallRedisDao.findHostCall(user.getUserId() + ""))
                user.setIsLine(2);
            // 判断用户是否勿扰
            if (user.getIsVideo() == 2)
                user.setIsLine(3);
            String showTime = ShowTimeUtil.getShowTime(user.getVisitorTime());
            user.setShowTime(showTime);
            return user;
        }).sorted(comparing(User::getVisitorTime).reversed()).collect(toList());
    }

    // 普通用户、所有用户v值排行榜
    @Cacheable(cacheNames = "commonCache", key = "T(String).valueOf(#page)")
    public List<User> getCommonUserList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        List<User> userList = new ArrayList<User>();
        List<String> userIds = stringRedisTemplate.opsForList().range("commonSort:all", startNum,
                startNum + pageSize - 1);
        if (userIds.size() == 0)
            return userList;
        List<Long> cids = userIds.stream().map(Long::parseLong).collect(toList());
        userList = userInfoDao.getCommonUserListByUserIds(cids);
        userList = userList.stream()
                .sorted(comparing(User::getIsVip).thenComparing(comparing(User::getvGradeSum).reversed()))
                .collect(toList());
        // 土豪等级
        List<Grade> gradeList = GradeCache.INSTANCE.getGradeList(2);
        userList.forEach(i -> {
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(i.getUserId() + ""))
                i.setIsLine(1);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            i.setvGrade(GradeUtil.getGradeCount(gradeList, i.getvGradeSum()));
        });
        return userList;
    }

    // 普通用户、在线用户v值排行榜
    public List<User> getCommonOnLineList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        Set<String> uIdSet = stringRedisTemplate.opsForZSet().reverseRange(RedisKeys.ZSET_COMMONSORTONLINE.getValue(),
                startNum, startNum + pageSize - 1);
        List<Long> cids = uIdSet.stream().map(Long::parseLong).collect(toList());
        List<User> userList = new ArrayList<User>();
        if (cids.size() == 0)
            return userList;
        userList = userInfoDao.getCommonUserListByUserIds(cids);
        //在线用户去掉 勿扰用户
        userList = userList.stream().filter(u -> u.getIsVideo() != 2).collect(toList());
        userList = userList.stream()
                .sorted(comparing(User::getIsVip).thenComparing(comparing(User::getvGradeSum).reversed()))
                .collect(toList());
        // 土豪等级
        List<Grade> gradeList = GradeCache.INSTANCE.getGradeList(2);
        userList.forEach(i -> {
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(i.getUserId() + ""))
                i.setIsLine(1);
            i.setvGrade(GradeUtil.getGradeCount(gradeList, i.getvGradeSum()));
        });
        return userList;
    }

    public User getUserInfoById(int id) {
        return userInfoDao.getUserInfoById(id);
    }

    public void addUserCallSum(int type, int fromUserId, int toUserId) {
        if (type == 1) {
            userCountDao.addUserCallSuccessSum(toUserId);
        } else {
            userCountDao.addUserCallFailSum(toUserId);
//            userCallMq.userCallFailMessageMq(type, fromUserId,toUserId);
        }
    }

    public UserStatusVO getUserStatusVO(Long userId) {
        UserStatusVO vo = new UserStatusVO();

        User user = userInfoDao.getUserById(userId);
        if (user == null) {
            throw new ConsumeRuntimeException(RESOURCE_NOT_FOUND);
        }
        boolean receiveVideo = user.getIsVideo() == 1;
        boolean receiveCall = user.getIsCall() == 1;
        Boolean flag = lineTimeRedisDao.hasKeyLine(userId.toString());

        if (flag) {
            //!receiveCall &&
            if (!receiveVideo) {
                //勿扰
                vo.setLineStatus(UserLineStatusConstant.NOT_DISTURB);
            } else if (userCallRedisDao.findHostCall(userId.toString())) {
                //繁忙
                vo.setLineStatus(UserLineStatusConstant.BUSY);
            } else {
                //在线
                vo.setLineStatus(UserLineStatusConstant.ON_LINE);
            }
        } else {
            //离线
            vo.setLineStatus(UserLineStatusConstant.OUT_LINE);
        }

        //是否主播
        vo.setBoolAnchor(user.getIsHost() == 1);

        vo.setReceiveCall(receiveCall);
        vo.setReceiveVideo(receiveVideo);
        vo.setChatPrice(user.getChatPrice());
        vo.setVideoPrice(user.getVideoPrice());
        return vo;
    }

    /**
     * 设置主播列表基础信息
     *
     * @param user
     */
    private void userInfoOrnament(User user) {
        List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
        List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
        //魅力等级
        user.setmGrade(GradeUtil.getGradeCount(mgradeList, user.getmGradeSum()));
        // 土豪等级
        user.setvGrade(GradeUtil.getGradeCount(vgradeList, user.getvGradeSum()));

        // 生日转换成年龄
        if (user.getBirthday() != null) {
            user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
            user.setBirthdayInstant(user.getBirthday().toString());
        }
        List<Label> labels = labelService.getLabelCountByUserId(user.getUserId());
        if (labels.size() > 3) {
            labels = new ArrayList<>(labels.subList(0, 3));
        }
        user.setLabelList(labels);
        //主播状态设置 0离线，1在线，2繁忙，3勿扰
        // 判断用户是否在线
        if (lineTimeRedisDao.isMember(user.getUserId() + ""))
            user.setIsLine(1);
        //如果用户为主播且正在通话中，则为繁忙状态
        if (user.getIsHost() == 1 && userCallRedisDao.findHostCall(user.getUserId() + ""))
            user.setIsLine(2);
        // 判断用户是否勿扰
        if (user.getIsVideo() == 2)
            user.setIsLine(3);
        //获取接通率
        double callSum = user.getCallSuccessSum() + user.getCallFailSum();
        if (callSum != 0) {
            double rate = (Double.parseDouble(user.getCallSuccessSum() + "") / callSum);
            user.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
        } else {
            user.setCallRate("100%");
        }
    }


    // 普通用户、所有用户v值排行榜
    @Cacheable(cacheNames = "commonHavingCache", key = "T(String).valueOf(#page)")
    public List<User> getCommonHavingList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        List<User> userList = new ArrayList<User>();
        List<String> userIds = stringRedisTemplate.opsForList().range("commonHaving:all", startNum,
                startNum + pageSize - 1);
        if (userIds.size() == 0)
            return userList;
        List<Long> cids = userIds.stream().map(Long::parseLong).collect(toList());
        userList = userInfoDao.getCommonUserListByUserIds(cids);
        // 土豪等级
        List<Grade> gradeList = GradeCache.INSTANCE.getGradeList(2);
        //存放有状态用户
        List<User> lineList = new ArrayList<User>();
        //无状态用户
        List<User> offLineList = new ArrayList<User>();
        for (User i : userList) {
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(i.getUserId() + ""))
                i.setIsLine(1);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            i.setvGrade(GradeUtil.getGradeCount(gradeList, i.getvGradeSum()));
            if (i.getIsLine() != 0) {
                lineList.add(i);
            } else {
                offLineList.add(i);
            }
        }
        //有状态用户排序
        lineList = lineList.stream().sorted(comparing(User::getIsLine)
                .thenComparing(User::getIsVip)
                .thenComparing(comparing(User::getvGradeSum).reversed())
        ).collect(Collectors.toList());
        offLineList = offLineList.stream().sorted(comparing(User::getIsVip)
                .thenComparing(comparing(User::getvGradeSum).reversed())
        ).collect(Collectors.toList());
        //合并根据状态区分存贮的list
        lineList.addAll(offLineList);
        return lineList;
    }

    public void updateUserCoverUrl(long id, String userCoverUrl) {
        if (userRedisDao.hasKeyCheckUserCoverUrl(id)) {
            userRedisDao.deleteCheckUserCoverUrl(id);
        }

        User user = userInfoDao.getUserById(id);
        if (user.getIsHost() == 1) {
            userRedisDao.putCheckUserCoverUrlForHost(id, user.getNickName(), userCoverUrl);
        } else {
            userRedisDao.putCheckUserCoverUrl(id, user.getNickName(), userCoverUrl);
        }
        //发送系统点对点消息
        String msg2 = "您的封面已提交修改，请耐心等待审核~";
        systemMessageUtil.sendSystemMessage(id, msg2);

        //发送点对点普通消息
//        JSONObject body = new JSONObject();
//        //开发者扩展字段
//        JSONObject ext = new JSONObject();
//            String msg2 = "您的封面已提交修改，请耐心等待审核~";
////        body.put("msg", msg2);
////
////        //发送给主播用户
////        try {
////            String temp = NetEaseCloudUserService.getSendMsg((long) id, robotSendMessageUserId,
////                    EnumType.TEXT_MESSAGE.state, body.toString(), ext.toString(), "");
////            if (!temp.substring(temp.indexOf("code") + 6, temp.indexOf("code") + 9).equals("200"))
////                logger.error("发送普通消息异常-云信：userId={},message={}", id, temp);
////        } catch (Exception e) {
////            logger.error("发送普通消息异常：userId={},error={}", id, e);
////        }
    }

    //type=1 最热主播列表
//    @Cacheable(cacheNames = "qualityHostCache", key = "T(String).valueOf(#page)")
    public List<User> getQualityHostList(long userId, int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);

        List<User> userList = new ArrayList<User>();
        List<String> userJsonList = stringRedisTemplate.opsForList().range("qualityHost:all", startNum,
                startNum + pageSize - 1);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                Optional<Long> countFollow = followRedisDao.countFollow(userId, user.getUserId());
                if (userId == user.getUserId() || countFollow.isPresent()) {
                    user.setIsFollow(1);
                } else {
                    user.setIsFollow(2);
                }
                User userInfoById = userInfoDao.getUserInfoById(user.getUserId());
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(userInfoById.getIntegralSum());
                HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                user.setHostUserLevelVo(hostUserLevel);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                userList.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

        });
        return userList;
    }


    //type=2 最新主播列表
//    @Cacheable(cacheNames = "newQualityHostCache", key = "T(String).valueOf(#page)")
    public List<User> getNewQualityHostList(int page, int pageSize, HttpServletRequest request) {
        //获取在线女主播id
        List<User> list = new ArrayList<>();
        CommonHead com = VerifyUtil.verifyCommonHead(request);
        //是否正在审核
        OpenApiStatus ops = openApiService.getOpenApi(com);
        //在审核
        if (ops != null && ops.getForwardAudit() && ops.getBackAudit()) {

            String appUserList = appkeyService.getAppKeyByKey("newHostIdOpenApi").getValue();
            String[] userIds = appUserList.split(",");
            if (userIds.length > 0) {
                for (String userId : userIds) {
                    User user = userInfoDao.getUserInfoById(Long.parseLong(userId));
                    IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService
                            .getUserIntegralLevel(user.getIntegralSum());
                    HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                    user.setHostUserLevelVo(hostUserLevel);
                    UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
                    user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                    list.add(user);
                }
                return list;
            } else {
                return new ArrayList<>();
            }
        }
        //未审核
        List<String> userJsonList = stringRedisTemplate.opsForList().range("newQualityHost:all", 0,
                100);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                User userInfoById = userInfoDao.getUserInfoById(user.getUserId());
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(userInfoById.getIntegralSum());
                HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                user.setHostUserLevelVo(hostUserLevel);
                UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                list.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        });
        return list;
//        Set<String> hostLine = stringRedisTemplate.opsForZSet().reverseRange("onLineThreeDaysNewHost",
//                0, 200);
//        logger.info("hostLine:::" + hostLine);
//        if (hostLine == null) {
//            return new ArrayList<>();
//        }
//        Set<String> isTopUserSet = stringRedisTemplate.opsForZSet().range("userHostNewZset", 0, -1);
//        logger.info("isTopUserSet:::" + isTopUserSet);
//        if (isTopUserSet != null && isTopUserSet.size() > 0) {
//            for (String userId : isTopUserSet) {
//                hostLine.remove(userId);
//            }
//        }
//        if (hostLine.size() > 0) {
//            List<User> userList = userInfoDao.getVisitorListByUserId(
//                    hostLine.stream().map(Long::parseLong).collect(toList()));
//            logger.info("userList:::" + userList.size());
//            //给女主播赋值后添加到集合中
//            getHostUserInfo(userList);
//            //1.5.3只显示在线用户，根据主播积分倒序
//            list = userList.stream().filter(user -> user.getIsLine() == 1)
//                    .sorted(comparing(User::getIntegralSum).reversed())
//                    .collect(Collectors.toList());
//            logger.info("list:::" + list.size());
//        }
//        //1.5.3置顶功能
//        if (isTopUserSet != null && isTopUserSet.size() > 0) {
//            List<Long> isTopUserIdList = isTopUserSet.stream().map(Long::parseLong).collect(toList());
//            List<User> isTopUserList = userInfoDao.getVisitorListByUserId(isTopUserIdList);
//            List<User> sortList = new ArrayList<>();
//            for (String str : isTopUserSet) {
//                for (User user : isTopUserList) {
//                    if (user.getUserId() == Long.parseLong(str)) {
//                        sortList.add(user);
//                        continue;
//                    }
//                }
//            }
//            getHostUserInfo(sortList);
//            sortList = sortList.stream().filter(user -> user.getIsLine() == 1).collect(Collectors.toList());
//            logger.info("isTopUserList:::" + sortList.size());
//            if (sortList.size() > 0) {
//                //置顶的位置为固定的2,3,6三个
//                int[] isTpoArray = {2, 3, 6};
//                for (int i = 0; i < sortList.size(); i++) {
//                    logger.info("isTpoArray[i]:::" + isTpoArray[i]);
//                    logger.info("sortList.get(i):::" + sortList.get(i).getUserId());
//                    if (list.size() >= (isTpoArray[i] - 1)) {
//                        list.add(isTpoArray[i] - 1, sortList.get(i));
//                    } else {
//                        list.add(sortList.get(i));
//                    }
//                }
//            }
//        }
//        logger.info("returnlist:::" + list.size());
//        return list;
    }

    private void getHostUserInfo(List<User> userList) {
        for (User user : userList) {
            IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService
                    .getUserIntegralLevel(user.getIntegralSum());
            HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
            user.setHostUserLevelVo(hostUserLevel);
            UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
            user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
        }
    }

    //type=3 主播列表-密先生
//    @Cacheable(cacheNames = "manHostCache", key = "T(String).valueOf(#page)")
    public List<User> getManHostList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        List<User> userList = new ArrayList<User>();
        List<String> userJsonList = stringRedisTemplate.opsForList().range("manHost:all", startNum,
                startNum + pageSize - 1);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                userList.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

        });
        return userList;
    }

    /**
     * 萌新列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public List<User> getOnlineThreeDaysNewUserList(int page, int pageSize) {
//        int startNum = PageUtil.getOffset(page, pageSize);
        Set<String> userIds = stringRedisTemplate.opsForZSet().reverseRange("onLineThreeDaysNewUser",
                0, 500);
        if (userIds == null || userIds.size() == 0) {
            return null;
        }
        List<Long> cids = userIds.stream().map(Long::parseLong).collect(toList());
        List<User> userList = userInfoDao.getQualityOnLineUserByUserIds(cids);
        int size = userList.size();
        if (size > 200) {
            size = 200;
        }
        userList = ListGroupUtil.createRandomList(userList, size);
        userList.forEach(i -> {
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            i.setIsLine(1);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            i.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(i.getUserId(), 1));
            i.setEnergyLevel(energyLevelService.getUserEnergyLevel(i.getEnergySum()));
            if (i.getLocationCity() == null || i.getLocationCity().equals("")) {
                i.setLocationCity("保密");
            }
        });
        return userList.stream().filter(i -> i.getIsLine() == 1).collect(toList());
    }

    /**
     * type=8
     * 壕友列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public List<User> getOnlineRechargeAmountUser(int page, int pageSize) {
//        int startNum = PageUtil.getOffset(page, pageSize);
        Set<String> userIds = stringRedisTemplate.opsForZSet().reverseRange("onLineRechargeAmountUser",
                0, 500);
        if (userIds == null || userIds.size() == 0) {
            return null;
        }
        List<Long> cids = userIds.stream().map(Long::parseLong).collect(toList());
        List<User> userList = userInfoDao.getQualityOnLineUserByUserIds(cids);
        int size = userList.size();
        if (size > 200) {
            size = 200;
        }
        userList = ListGroupUtil.createRandomList(userList, size);
        userList.forEach(i -> {
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            i.setIsLine(1);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            i.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(i.getUserId(), 1));
            i.setEnergyLevel(energyLevelService.getUserEnergyLevel(i.getEnergySum()));
            if (i.getLocationCity() == null || i.getLocationCity().equals("")) {
                i.setLocationCity("保密");
            }
        });
        return userList.stream().filter(i -> i.getIsLine() == 1).collect(toList());
    }

    //type=4 在线男女用户
    public List<User> getOnLineUsersList(int sex, int page, int pageSize) {
//        int startNum = PageUtil.getOffset(page, pageSize);
        int findSex = 1;
        if (sex == 1) {
            findSex = 2;
        }
        Set<String> userIds = userRedisDao.findOnLineUserBySex(findSex, 0, 500);
        if (userIds.size() == 0)
            return new ArrayList<>();
        List<Long> cids = userIds.stream().map(Long::parseLong).collect(toList());
        List<User> userList = userInfoDao.getQualityOnLineUserByUserIds(cids);
        int size = userList.size();
        if (size > 200) {
            size = 200;
        }
        userList = ListGroupUtil.createRandomList(userList, size);
        userList.forEach(i -> {
//            List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
//            List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
//            魅力等级
//            i.setmGrade(GradeUtil.getGradeCount(mgradeList, i.getmGradeSum()));
            // 土豪等级
//            i.setvGrade(GradeUtil.getGradeCount(vgradeList, i.getvGradeSum()));
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            i.setIsLine(1);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            //获取接通率
            double callSum = i.getCallSuccessSum() + i.getCallFailSum();
            if (callSum != 0) {
                double rate = (Double.parseDouble(i.getCallSuccessSum() + "") / callSum);
                i.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
            } else {
                i.setCallRate("100%");
            }
            i.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(i.getUserId(), 1));
            i.setEnergyLevel(energyLevelService.getUserEnergyLevel(i.getEnergySum()));
        });
//        if (findSex == 1) {
//            userList = userList.stream()
//                    .sorted(comparing(User::getvGradeSum).reversed())
//                    .collect(toList());
//        } else {
//            userList = userList.stream()
//                    .sorted(comparing(User::getmGradeSum).reversed())
//                    .collect(toList());
//        }
        return userList;

    }

    // type=5 颜值主播列表
//    @Cacheable(cacheNames = "beautyHostCache", key = "T(String).valueOf(#page)")
    public List<User> getBeautyHostList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        List<User> userList = new ArrayList<User>();
        List<String> userJsonList = stringRedisTemplate.opsForList().range("beautyHost:all", startNum,
                startNum + pageSize - 1);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                userList.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

        });
        return userList;
    }


    // type=6 蜜桃主播列表
//    @Cacheable(cacheNames = "figureHostCache", key = "T(String).valueOf(#page)")
    public List<User> getFigureHostList(int page, int pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);
        List<User> userList = new ArrayList<User>();
        List<String> userJsonList = stringRedisTemplate.opsForList().range("figureHost:all", startNum,
                startNum + pageSize - 1);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                userList.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

        });
        return userList;
    }


    public void updateUserVoiceSignature(long id, String voiceSignature, String voiceSignatureTime) {
        User user = userInfoDao.getUserInfoById(id);
        IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService
                .getUserIntegralLevel(user.getIntegralSum());
        if (userIntegralLevel.getIsModifyVoiceIntroduction() == 0) {
            throw new ConsumeRuntimeException("修改语音介绍功能未开通");
        }
        if (user.getIsHost() == 1 && userIntegralLevel.getIsModifyVoiceIntroduction() == 1) {
            Boolean ishaveVoice = userRedisDao.getUserInfoCheckVoice(id);
            if (ishaveVoice) {
                userRedisDao.delUserInfoCheckVoice(id);
                userRedisDao.userInfoCheckVoice(id, voiceSignature, voiceSignatureTime);
            } else {
                userRedisDao.userInfoCheckVoice(id, voiceSignature, voiceSignatureTime);
            }
        } else {
            if (user.getIsHost() != 1) {
                throw new ConsumeRuntimeException("您还不是主播，无法添加语音介绍");
            } else {
                throw new ConsumeRuntimeException("主播等级不够");
            }
        }
    }

    /**
     * 主播资料页
     *
     * @param userId
     * @return
     */
    public JSONObject getHostUserMaterial(long tokenId, long userId) {
        User user = userInfoDao.getUserInfoById(userId);
        if (tokenId == userId) {
            if (user.getIsHost() != 1) {
                throw new ConsumeRuntimeException("您不是主播");
            }
        }
        if (user != null) {
            List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
            List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
            //魅力等级
            user.setmGrade(GradeUtil.getGradeCount(mgradeList, user.getmGradeSum()));
            // 土豪等级
            user.setvGrade(GradeUtil.getGradeCount(vgradeList, user.getvGradeSum()));
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("user", user);

        //获取用户的亲密守护
        List<User> userlist = new ArrayList<>();
        List<BillDetail> billList = billDetailService.getBillDetailForUser(userId, 1, 5);
        if (billList.size() > 0) {
            for (BillDetail billDetail : billList) {
                if (billDetail.getOutUserId() != 0) {
                    User user1 = userInfoDao.getUserIconByUserId(billDetail.getOutUserId());
                    userlist.add(user1);
                }
            }
            if (userlist.size() > 0) {
                jsonObject.put("userGuardList", userlist);
            } else {
                jsonObject.put("userGuardList", new ArrayList<>());
            }
        } else {
            jsonObject.put("userGuardList", new ArrayList<>());
        }

        //获取主播收到的全部礼物(全部展示，不分页)
        List<GiftSpend> giftSpendList = giftSpendService.gitGiftSpendByInUserId(userId);
        if (giftSpendList.size() > 0) {
            jsonObject.put("userGiftList", giftSpendList);
        } else {
            jsonObject.put("userGiftList", new ArrayList<>());
        }
        // 获取用户评价
        //根据主播id 查询用户评价列表
        List<UserAssessLabel> userAssessLabelList = labelService.getUserAssessLabel(userId);
        Map<Long, UserAssessLabelDTO> map = new HashMap<>();
        List<UserAssessLabelDTO> list = new ArrayList<>();
        if (userAssessLabelList.size() > 0) {
            for (UserAssessLabel userAssessLabel : userAssessLabelList) {
                //如果likeLabel.getUserId()这个key不存在
                if (!map.containsKey(userAssessLabel.getUserId())) {
                    UserAssessLabelDTO userAssessDTO = new UserAssessLabelDTO();
                    //获取用户信息
                    User userAss = userInfoDao.getUserById(userAssessLabel.getUserId());
                    userAssessDTO.setUserId(userAss.getUserId());
                    userAssessDTO.setIcon(userAss.getIcon());
                    userAssessDTO.setUserName(userAss.getNickName());
                    List<UserAssessLabel> userAssessList = new ArrayList<>();
                    String labelName = labelService.getLabelName((long) userAssessLabel.getLabelId());
                    userAssessLabel.setLabelName(labelName);
                    userAssessList.add(userAssessLabel);
                    userAssessDTO.setLabelList(userAssessList);
                    map.put(userAssessLabel.getUserId(), userAssessDTO);
                    list.add(map.get(userAssessLabel.getUserId()));
                } else {
                    //如果likeLabel.getUserId()这个key存在
                    String labelName = labelService.getLabelName((long) userAssessLabel.getLabelId());
                    userAssessLabel.setLabelName(labelName);
                    map.get(userAssessLabel.getUserId()).getLabelList().add(userAssessLabel);
                }
            }
        } else {
            new ArrayList<>();
        }
        if (list.size() > 10) {
            list.subList(0, 9);
        }
        jsonObject.put("userAssessList", list);
        return jsonObject;
    }

    /**
     * 寻寻1.5.1 发现列表获取4个主播实现
     *
     * @param
     * @return
     */
    public JSONObject getHostUser(HttpServletRequest request) {
        JSONObject jsonObject = new JSONObject();
        List<User> list = new ArrayList<>();
        CommonHead com = VerifyUtil.verifyCommonHead(request);
        //是否正在审核
        OpenApiStatus ops = openApiService.getOpenApi(com);

        if (ops != null && ops.getForwardAudit() && ops.getBackAudit()) {
            //在审核
            String appUserList = appkeyService.getAppKeyByKey("openApiUserId").getValue();
            String[] userIds = appUserList.split(",");
            if (userIds != null && userIds.length > 0) {
                if (userIds.length < 4) {
                    for (String userId : userIds) {
                        User user = userInfoDao.getUserInfoById(Long.parseLong(userId));

                        list.add(user);
                    }
                } else {
                    for (String userId : userIds) {
                        User user = userInfoDao.getUserInfoById(Long.parseLong(userId));

                        user.setIsLine(1);
                        list.add(user);
                    }
                    List<User> randomList = ListGroupUtil.createRandomList(list, 4);
                    randomList.forEach(user -> {
                        IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum());
                        HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                        user.setHostUserLevelVo(hostUserLevel);
                        UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
                    });

                    jsonObject.put("highHostUserList", randomList.subList(0, 2));
                    jsonObject.put("lowerHostUserList", randomList.subList(2, 4));
                }
                return jsonObject;
            } else {
                JSONObject json = new JSONObject();
                json.put("highHostUserList", new ArrayList<>());
                json.put("lowerHostUserList", new ArrayList<>());
                return json;
            }

        }
        //获取发现列表
        //获取在线列表（只有女主播）

        Set<String> hostLine = lineTimeRedisDao.getHostLineBySex(2);
        List<User> highHostUserList = new ArrayList<>();
        List<User> lowerHostUserList = new ArrayList<>();
        if (hostLine.size() == 0) {
            return new JSONObject();
        }
        for (String userId : hostLine) {
            User userInfo = userInfoDao.getUserInfoById(Long.parseLong(userId));
            IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService
                    .getUserIntegralLevel(userInfo.getIntegralSum());
            if (userInfo != null) {
                // 判断主播是否在线，设置主播状态
                if (lineTimeRedisDao.isMember(userInfo.getUserId() + "")) {
                    userInfo.setIsLine(1);
                }
                //如果用户为主播且正在通话中，则为繁忙状态
                if (userInfo.getIsHost() == 1 && userCallRedisDao.findHostCall(userInfo.getUserId() + ""))
                    userInfo.setIsLine(2);
                // 判断主播是否勿扰
                if (userInfo.getIsVideo() == 2)
                    userInfo.setIsLine(3);
                if (userInfo.getEnable() == 2)
                    userInfo.setIsLine(4);
                if (userInfo.getIsLine() == 1 && userIntegralLevel.getIntegralGrade() >= 5) {
                    highHostUserList.add(userInfo);
                } else if (userInfo.getIsLine() == 1 && userIntegralLevel.getIntegralGrade() < 5) {
                    lowerHostUserList.add(userInfo);
                }
                userInfo.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(userInfo.getUserId(), 1));
                userInfo.setHostUserLevelVo(HostUserLevelUtil.getHostUserLevel(userIntegralLevel));
            }
        }
        List<User> randomHighHostUserList = ListGroupUtil.createRandomList(highHostUserList, 2);
        for (User highHostUser : randomHighHostUserList) {
            UserAssignmentUtil.UserAssignment(highHostUser, lineTimeRedisDao, userCallRedisDao);
        }
        List<User> randomLowerHostUserList = ListGroupUtil.createRandomList(lowerHostUserList, 2);
        for (User lowerHostUser : randomLowerHostUserList) {
            UserAssignmentUtil.UserAssignment(lowerHostUser, lineTimeRedisDao, userCallRedisDao);
        }

        jsonObject.put("highHostUserList", randomHighHostUserList);
        jsonObject.put("lowerHostUserList", randomLowerHostUserList);
        return jsonObject;
    }

    /**
     * 寻寻1.5.1 关注列表
     * 列表排序（在线>主播等级(降序)>魅力等级(降序)>关注时间(降序)）
     *
     * @param id
     * @return
     */
    public List<User> getFollowHostUserList(long id) {

        List<User> userList = new ArrayList<User>();
        //获取用户关注的主播id
//        if(type==0){
//             folllowAllByUserId = followRedisDao.getMyFollowHost(id);
//        }else if(type==1){
//            folllowAllByUserId = followRedisDao.getMyFollowFROMHost(id);
//        }
        Set<Long> folllowAllByUserId = followRedisDao.getFolllowAllByUserId(id);

        if (folllowAllByUserId.size() == 0)
            return userList;
        //获取关注时间
        Map<Integer, String> map = followRedisDao.getFollowIdsById(id, 0, 0);
        //查询主播列表
        List<Long> followHostUserIds = new ArrayList<>(folllowAllByUserId);
        List<User> userHostList = userInfoDao.getUserForLabelByUserIds(followHostUserIds);
        //给主播赋值
        User userById = userInfoDao.getUserById(id);
        if (userById.getIsHost() == 2) {
            for (User hostUser : userHostList) {
                if (hostUser.getIsHost() == 1) {
                    userList.add(hostUser);
                }
            }
        } else {
            for (User hostUser : userHostList) {
                if (hostUser.getIsHost() == 2) {
                    userList.add(hostUser);
                }
            }
        }

        if (userList.size() == 0) {
            return new ArrayList<>();
        }
        userList.forEach(i -> {
            List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
            List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
            //魅力等级
            i.setmGrade(GradeUtil.getGradeCount(mgradeList, i.getmGradeSum()));
            // 土豪等级
            i.setvGrade(GradeUtil.getGradeCount(vgradeList, i.getvGradeSum()));
            // 生日转换成年龄
            if (i.getBirthday() != null) {
                i.setAge(SumAgeUtil.getAgeByBirth(i.getBirthday()));
                i.setBirthdayInstant(i.getBirthday().toString());
            }
            if (i.getIsHost() == 2) {
                // 判断用户是否在线
                if (lineTimeRedisDao.hasKeyLine(i.getUserId() + ""))
                    i.setIsLine(1);
            } else if (i.getIsHost() == 1) {
                // 判断主播是否在线
                if (lineTimeRedisDao.isMember(i.getUserId() + ""))
                    i.setIsLine(1);
                //如果用户为主播且正在通话中，则为繁忙状态
                if (i.getIsHost() == 1 && userCallRedisDao.findHostCall(i.getUserId() + ""))
                    i.setIsLine(2);
            }

            // 判断主播是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            if (i.getEnable() == 2)
                i.setIsLine(4);

            //获取接通率
            double callSum = i.getCallSuccessSum() + i.getCallFailSum();
            if (callSum != 0) {
                double rate = (Double.parseDouble(i.getCallSuccessSum() + "") / callSum);
                i.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
            } else {
                i.setCallRate("100%");
            }
            i.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(i.getUserId(), 1));
            //赋值关注时间
//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            i.setFollowDate(map.get((int) i.getUserId()));
            i.setEnergyLevel(energyLevelService.getUserEnergyLevel(i.getEnergySum()));
        });
        //创建在线列表
        List<User> hostUserList = new ArrayList<>();
        //创建离线列表
        List<User> userOfflineList = new ArrayList<>();
        //创建封号列表
        List<User> userEnableList = new ArrayList<>();
        for (User user : userList) {
            //根据用户状态存放相应的list集合中
            if (user.getIsLine() > 0 && user.getIsLine() <= 3) {
                hostUserList.add(user);
            } else if (user.getIsLine() == 0) {
                userOfflineList.add(user);
            } else {
                userEnableList.add(user);
            }
        }

        //列表排序（在线>主播等级(降序)>魅力等级(降序)>关注时间(降序)）
        hostUserList = hostUserList.stream().sorted(comparing(User::getIsLine)
                .thenComparing(comparing(User::getFollowDate).reversed())
        ).collect(Collectors.toList());
        //离线列表排序（主播等级(降序)>魅力等级(降序)>关注时间(降序)）
        if (userOfflineList.size() > 0) {
            userOfflineList = userOfflineList.stream().sorted(comparing(User::getFollowDate).reversed()
            ).collect(Collectors.toList());
            hostUserList.addAll(userOfflineList);
        }
        if (userOfflineList.size() > 0) {
            userEnableList = userEnableList.stream().sorted(comparing(User::getFollowDate).reversed()
            ).collect(Collectors.toList());
            hostUserList.addAll(userEnableList);
        }

        return hostUserList;
    }

    /**
     * 1.5.6 主播关注列表
     * @param id
     * @return
     */
    public List<User> getFollowHostUserListByUser(long id) {
        List<User> userList = new ArrayList<User>();
        Set<Long> followAllByUserId = followRedisDao.getFolllowAllByUserId(id);
        if (followAllByUserId.size() == 0)
            return userList;
        //获取关注时间
        Map<Integer, String> map = followRedisDao.getFollowIdsById(id, 0, 0);
        //查询主播列表
        List<Long> followHostUserIds = new ArrayList<>(followAllByUserId);
        List<User> userHostList = userInfoDao.getUserForLabelByUserIds(followHostUserIds);
        //给主播赋值
        for (User hostUser : userHostList) {
            if (hostUser.getIsHost() == 1) {
                userList.add(hostUser);
            }
        }
        if (userList.size() == 0) {
            return new ArrayList<>();
        }
        userList.forEach(i -> {
//            // 判断主播是否在线
//            if (lineTimeRedisDao.isMember(i.getUserId() + ""))
//                i.setIsLine(1);
//            //如果用户为主播且正在通话中，则为繁忙状态
//            if (i.getIsLine() == 1 && userCallRedisDao.findHostCall(i.getUserId() + ""))
//                i.setIsLine(2);
//            // 判断主播是否勿扰
//            if (i.getIsVideo() == 2)
//                i.setIsLine(3);
//            if (i.getEnable() == 2)
//                i.setIsLine(4);

            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(i.getUserId() + ""))
                i.setIsLine(1);
            //如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
            if (i.getIsHost() == 1 && userCallRedisDao.findHostCall(i.getUserId() + ""))
                i.setIsLine(2);
            // 判断用户是否勿扰
            if (i.getIsVideo() == 2)
                i.setIsLine(3);
            //判断用户是否被封停
            if (i.getEnable() == 2) {
                i.setIsLine(4);
            }

            //获取接通率
            double callSum = i.getCallSuccessSum() + i.getCallFailSum();
            if (callSum != 0) {
                double rate = (Double.parseDouble(i.getCallSuccessSum() + "") / callSum);
                i.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
            } else {
                i.setCallRate("100%");
            }
            i.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(i.getUserId(), 1));
            i.setFollowDate(map.get((int) i.getUserId()));
            i.setEnergyLevel(energyLevelService.getUserEnergyLevel(i.getEnergySum()));
        });
        //创建在线列表
        List<User> lineUserList = new ArrayList<>();
        //繁忙列表
        List<User> callUserList = new ArrayList<>();
        //创建离线列表
        List<User> userOfflineList = new ArrayList<>();
        //创建封号列表
        List<User> userEnableList = new ArrayList<>();


        //在线列表排序
        lineUserList = userList.stream().filter(i->i.getIsLine()==1).collect(Collectors.toList());
        for(User user : lineUserList){
            user.setHourIncome(lineTimeRedisDao.getHomeListIncomeByHostUserByUserId(user.getUserId()));
        }
        lineUserList = lineUserList.stream().sorted(comparing(User::getHourIncome).reversed()
                .thenComparing(comparing(User::getIntegralSum).reversed())).collect(toList());
        //繁忙排序
        callUserList = userList.stream().filter(i->i.getIsLine()==2 || i.getIsLine()==3)
                .sorted(comparing(User::getEnergySum).reversed()).collect(toList());
        //封号排序
        userEnableList = userList.stream().filter(i->i.getIsLine()==4)
                .sorted(comparing(User::getEnergySum).reversed()).collect(toList());
        //离线排序
        userOfflineList = userList.stream().filter(i->i.getIsLine()==0).collect(toList());
        if(userOfflineList.size()>0){
            for(User user: userOfflineList){
                Double singOutDateTime = lineTimeRedisDao.getHostUserSingOutDateTimeByHost(user.getUserId());
                user.setSingOutDateTime(singOutDateTime);
                logger.error("userId:::"+user.getUserId()+",sing:::"+singOutDateTime);
                user.setSingOutDateTimeStr(DateUtil.getSingOutDateTime(singOutDateTime.longValue()));
            }
        }
        userOfflineList = userOfflineList.stream().sorted(comparing(User::getSingOutDateTime).reversed()
                .thenComparing(comparing(User::getEnergySum).reversed())).collect(toList());
        lineUserList.addAll(callUserList);
        lineUserList.addAll(userOfflineList);
        lineUserList.addAll(userEnableList);
        return lineUserList;
    }

    /**
     * 1.5.1 安卓版热门列表
     * 1.5.6
     * 在线女主播（不分页）
     * @return
     */
    public List<User> getLineHostUserList(HttpServletRequest request) {
        //获取在线女主播id
        List<User> list = new ArrayList<>();
        CommonHead com = VerifyUtil.verifyCommonHead(request);
        //是否正在审核
        OpenApiStatus ops = openApiService.getOpenApi(com);

        if (ops != null && ops.getForwardAudit() && ops.getBackAudit()) {
            //在审核
            String appUserList = appkeyService.getAppKeyByKey("openApiUserId").getValue();
            String[] userIds = appUserList.split(",");
            if (userIds.length > 0) {
                for (String userId : userIds) {
                    User user = userInfoDao.getUserInfoById(Long.parseLong(userId));
                    IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum());
                    HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                    user.setHostUserLevelVo(hostUserLevel);
                    UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
                    user.setSingOutDateTimeStr("1小时前");
                    list.add(user);
                }
                return list;
            } else {
                return new ArrayList<>();
            }
        }
        //未审核
        List<String> userJsonList = stringRedisTemplate.opsForList().range("qualityHost:all", 0,
                100);
        ObjectMapper mapper = new ObjectMapper();
        userJsonList.forEach(i -> {
            try {
                User user = mapper.readValue(i, User.class);
                User userInfoById = userInfoDao.getUserInfoById(user.getUserId());
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(userInfoById.getIntegralSum());
                HostUserLevelVo hostUserLevel = HostUserLevelUtil.getHostUserLevel(userIntegralLevel);
                user.setHostUserLevelVo(hostUserLevel);
                UserAssignmentUtil.UserAssignment(user, lineTimeRedisDao, userCallRedisDao);
                user.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(user.getUserId(), 1));
                list.add(user);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        });
        return list;
//        //未审核
//        Set<String> hostLine = lineTimeRedisDao.getHostLineBySex(2);
//        if (hostLine.size() == 0) {
//            return new ArrayList<>();
//        }
//        List<Long> cids = hostLine.stream().map(Long::parseLong).collect(toList());
//        if (cids.size() > 200) {
//            cids = cids.subList(0, 200);
//        }
//        Set<String> isTopUserSet = stringRedisTemplate.opsForZSet().range("userHostHotZset", 0, -1);
//        if (isTopUserSet != null && isTopUserSet.size() > 0) {
//            for (String userId : isTopUserSet) {
//                cids.remove(Long.parseLong(userId));
//            }
//        }
//        if (cids.size() > 0) {
//            List<User> userList = userInfoDao.getVisitorListByUserId(cids);
//            //给女主播赋值后添加到集合中
//            getHostUserInfo(userList);
//            //1.5.3只显示在线用户，根据主播积分倒序
//            list = userList.stream().filter(user -> user.getIsLine() == 1)
//                    .sorted(comparing(User::getIntegralSum).reversed())
//                    .collect(Collectors.toList());
//        }
//        //1.5.3置顶功能
//        if (isTopUserSet != null && isTopUserSet.size() > 0) {
//            List<Long> isTopUserIdList = isTopUserSet.stream().map(Long::parseLong).collect(toList());
//            List<User> isTopUserList = userInfoDao.getVisitorListByUserId(isTopUserIdList);
//            List<User> sortList = new ArrayList<>();
//            for (String str : isTopUserSet) {
//                for (User user : isTopUserList) {
//                    if (user.getUserId() == Long.parseLong(str)) {
//                        sortList.add(user);
//                        continue;
//                    }
//                }
//            }
//            getHostUserInfo(sortList);
//            sortList = sortList.stream().filter(user -> user.getIsLine() == 1).collect(Collectors.toList());
//            if (sortList.size() > 0) {
//                //置顶的位置为固定的2,3,6三个
//                int[] isTpoArray = {2, 3, 6};
//                for (int i = 0; i < sortList.size(); i++) {
//                    if (list.size() >= (isTpoArray[i] - 1)) {
//                        list.add(isTpoArray[i] - 1, sortList.get(i));
//                    } else {
//                        list.add(sortList.get(i));
//                    }
//                }
//            }
//        }
    }

    public List<UserInfoDistanceDTO> getDistanceHostUserList(String location, HttpServletRequest request) {
        //获取在线女主播id
        CommonHead com = VerifyUtil.verifyCommonHead(request);
        //是否正在审核
        OpenApiStatus ops = openApiService.getOpenApi(com);
        List<UserInfoDistanceDTO> list = new ArrayList<>();
        if (ops != null && ops.getForwardAudit() && ops.getBackAudit()) {
            //在审核
            String appUserList = appkeyService.getAppKeyByKey("openApiUserId").getValue();
            String[] userIds = appUserList.split(",");
            if (userIds != null && userIds.length > 0) {
                for (String userId : userIds) {
                    User user = userInfoDao.getUserInfoById(Long.parseLong(userId));
                    UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();
                    BeanUtils.copyProperties(user, userInfoDistanceDTO);
                    IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum());
                    userInfoDistanceDTO.setUserLevel(userIntegralLevel.getIntegralGrade());
                    userInfoDistanceDTO.setUserLevelPic(userIntegralLevel.getIntegralGradePic());
                    userInfoDistanceDTO.setIsHost(user.getIsHost());
                    userInfoDistanceDTO.setUserLevelName(userIntegralLevel.getIntegralTitleName());
                    userInfoDistanceDTO.setDistance("未知");
                    userInfoDistanceDTO.setIsLine(1);
                    list.add(userInfoDistanceDTO);
                }
                return list;
            } else {
                return new ArrayList<>();
            }
        }

        //不是审核走下面的代码
        Set<String> hostLine = lineTimeRedisDao.getHostLineBySex(2);

        if (hostLine.size() == 0) {
            return new ArrayList<>();
        }

        if (!StringUtils.isEmpty(location)) {
            for (String hostUserId : hostLine) {
                //获取主播用户信息并赋值
                User hostUser = userInfoDao.getUserInfoById(Long.parseLong(hostUserId));
                UserAssignmentUtil.UserAssignment(hostUser, lineTimeRedisDao, userCallRedisDao);
                hostUser.setUserCoverUrlList(userCoverUrlDao.getUserCoverUrlByUserId(hostUser.getUserId(), 1));
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(hostUser.getIntegralSum());
                //在线主播计算距离
                if (hostUser != null) {
                    if (StringUtils.isEmpty(hostUser.getLocation())) {
                        hostUser.setLocation(LocationConstant.DEFAULT_LATITUDE_AND_LONGITUDE);
                    }
                    if (hostUser.getIsLine() == 1) {
                        //获取用户的经纬度(前：纬度，后：经度)
                        String[] userArray = location.split(",");
                        List<Double> userLocation = new ArrayList<>();
                        for (int i = 0, len = userArray.length; i < len; i++) {
                            userLocation.add(Double.parseDouble(userArray[i]));
                        }
                        //获取主播的经纬度(前：纬度，后：经度)
                        String[] hostUserArray = hostUser.getLocation().split(",");
                        List<Double> hostUserLocation = new ArrayList<>();
                        for (int i = 0, len = hostUserArray.length; i < len; i++) {
                            hostUserLocation.add(Double.parseDouble(hostUserArray[i]));
                        }
                        //计算用户与主播的距离
                        double distance = DistanceUtil.getDistance(userLocation.get(0), userLocation.get(1),
                                hostUserLocation.get(0), hostUserLocation.get(1));
                        List<UserInfoDistanceDTO> userList = new ArrayList<>();
                        UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();

                        BeanUtils.copyProperties(hostUser, userInfoDistanceDTO);
                        if (distance < 1) {
                            userInfoDistanceDTO.setDistance("<1km");
                        } else if (distance >= 1 && distance < 800) {
                            userInfoDistanceDTO.setDistance((int) Math.round(distance) + "km");
                        } else if (distance >= 800) {
                            userInfoDistanceDTO.setDistance(">800km");
                        }
                        userInfoDistanceDTO.setUserLevel(userIntegralLevel.getIntegralGrade());
                        userInfoDistanceDTO.setUserLevelPic(userIntegralLevel.getIntegralGradePic());
                        userInfoDistanceDTO.setUserLevelName(userIntegralLevel.getIntegralTitleName());
                        userInfoDistanceDTO.setIsHost(hostUser.getIsHost());
                        userInfoDistanceDTO.setSort((int) Math.round(distance));
                        userList.add(userInfoDistanceDTO);
                        list.addAll(userList);
                    }
                }
            }
            if (list.size() > 0) {
                if (list.size() > 4) {
                    list.subList(0, 4);
                }
                Collections.sort(list);

            } else {
                return new ArrayList<>();
            }

        } else {
            //地理位置为空 随机给四个在线主播
            List<UserInfoDistanceDTO> noDistanceUser = new ArrayList<>();
            for (String hostUserId : hostLine) {
                //获取主播用户信息并赋值
                User hostUser = userInfoDao.getUserInfoById(Long.parseLong(hostUserId));
                UserAssignmentUtil.UserAssignment(hostUser, lineTimeRedisDao, userCallRedisDao);

                if (hostUser != null) {
                    if (hostUser.getIsLine() == 1) {
                        UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();
                        BeanUtils.copyProperties(hostUser, userInfoDistanceDTO);
                        userInfoDistanceDTO.setDistance("未知");
                        noDistanceUser.add(userInfoDistanceDTO);
                    }
                }
            }
            List<UserInfoDistanceDTO> randomList = ListGroupUtil.createRandomList(noDistanceUser, 4);
            // randomList.subList(0,3);
            list.addAll(randomList);
        }

        return list;
    }

    /**
     * 主播修改位置
     *
     * @param appkey
     * @param userId
     * @param location 经纬度 格式：纬度(lat),经度(lon)
     */
    public void updateHostLocation(Appkey appkey, long userId, String location) throws Exception {

        User user = userInfoDao.getUserInfoById(userId);
        IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum());
        if (userIntegralLevel.getIsModifyLocation() == 1) {
            if (user.getIsHost() != 1) {
                throw new ConsumeRuntimeException("只用主播才能修改位置");
            }

            String lat = location.split(",")[0];
            String lon = location.split(",")[1];
            LocationDTO locationDTO = new LocationDTO();
            locationDTO.setLat(lat);
            locationDTO.setLon(lon);
            LocationUtil.getProvinceAndCity(GaodeConfig.REGEO_URL, GaodeConfig.getKey(), locationDTO);

            if (StringUtils.isEmpty(locationDTO.getProvince()) || StringUtils.isEmpty(locationDTO.getCity())) {
                throw new ConsumeRuntimeException("地理位置不正确");
            }

            if(locationDTO.getProvince().equals("北京市")
                    ||locationDTO.getProvince().equals("天津市")
                    ||locationDTO.getProvince().equals("上海市")||locationDTO.getProvince().equals("重庆市")){
                hostRealTimeLocationRedisDao.setAll(user.getUserId(),location,
                        locationDTO.getProvince(),
                        locationDTO.getProvince());
                userInfoDao.updateUserLocation(user.getUserId(), locationDTO.getProvince(),
                        locationDTO.getProvince(), location);
            }else {
                userInfoDao.updateUserLocation(user.getUserId(), locationDTO.getCity(),
                        locationDTO.getProvince(), location);
            }

            userInfoCache.deleteUserCacheInfo(user.getUserId());
        } else {
            throw new ConsumeRuntimeException("修改位置功能未开通");
        }
    }

    /**
     * @param location
     * @return
     */
    public List<UserInfoDistanceDTO> getDistanceHostUserListForAndroid(String location, HttpServletRequest request) {

        CommonHead com = VerifyUtil.verifyCommonHead(request);
        //是否正在审核
        OpenApiStatus ops = openApiService.getOpenApi(com);
        List<UserInfoDistanceDTO> list = new ArrayList<>();
        if (ops != null && ops.getForwardAudit() && ops.getBackAudit()) {
            //在审核
            String appUserList = appkeyService.getAppKeyByKey("openApiUserId").getValue();
            String[] userIds = appUserList.split(",");
            if (userIds != null && userIds.length > 0) {
                for (String userId : userIds) {
                    User user = userInfoDao.getUserInfoById(Long.parseLong(userId));
                    UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();
                    BeanUtils.copyProperties(user, userInfoDistanceDTO);
                    userInfoDistanceDTO.setDistance("未知");
                    userInfoDistanceDTO.setIsLine(1);
                    list.add(userInfoDistanceDTO);
                }
                return list;
            } else {
                return new ArrayList<>();
            }
        }
        //获取在线女主播id
        Set<String> hostLine = lineTimeRedisDao.getHostLineBySex(2);

        if (hostLine.size() == 0) {
            return new ArrayList<>();
        }
        if (!StringUtils.isEmpty(location)) {
            for (String hostUserId : hostLine) {
                //获取主播用户信息并赋值
                User hostUser = userInfoDao.getUserInfoById(Long.parseLong(hostUserId));
                UserAssignmentUtil.UserAssignment(hostUser, lineTimeRedisDao, userCallRedisDao);
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(hostUser.getIntegralSum());
                //在线主播计算距离
                if (hostUser != null) {
                    if (StringUtils.isEmpty(hostUser.getLocation())) {
                        hostUser.setLocation(LocationConstant.DEFAULT_LATITUDE_AND_LONGITUDE);
                    }
                    if (hostUser.getIsLine() == 1) {
                        //获取用户的经纬度(前：纬度，后：经度)
                        String[] userArray = location.split(",");
                        List<Double> userLocation = new ArrayList<>();
                        for (int i = 0, len = userArray.length; i < len; i++) {
                            userLocation.add(Double.parseDouble(userArray[i]));
                        }
                        //获取主播的经纬度(前：纬度，后：经度)
                        String[] hostUserArray = hostUser.getLocation().split(",");
                        List<Double> hostUserLocation = new ArrayList<>();
                        for (int i = 0, len = hostUserArray.length; i < len; i++) {
                            hostUserLocation.add(Double.parseDouble(hostUserArray[i]));
                        }
                        //计算用户与主播的距离
                        double distance = DistanceUtil.getDistance(userLocation.get(0), userLocation.get(1),
                                hostUserLocation.get(0), hostUserLocation.get(1));
                        List<UserInfoDistanceDTO> userList = new ArrayList<>();
                        UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();
                        userInfoDistanceDTO.setUserLevel(userIntegralLevel.getIntegralGrade());
                        userInfoDistanceDTO.setUserLevelPic(userIntegralLevel.getIntegralGradePic());
                        userInfoDistanceDTO.setUserLevelName(userIntegralLevel.getIntegralTitleName());
                        userInfoDistanceDTO.setIsHost(hostUser.getIsHost());
                        userInfoDistanceDTO.setSort((int) Math.round(distance));
                        BeanUtils.copyProperties(hostUser, userInfoDistanceDTO);
                        userInfoDistanceDTO.setDistance((String.valueOf((int) Math.round(distance))));
                        userList.add(userInfoDistanceDTO);
                        list.addAll(userList);
                    }
                }
            }
            if (list.size() > 0) {
                Collections.sort(list);
            } else {
                return new ArrayList<>();
            }

        } else {
            //地理位置为空 所有在线主播
            List<UserInfoDistanceDTO> noDistanceUser = new ArrayList<>();
            for (String hostUserId : hostLine) {
                //获取主播用户信息并赋值
                User hostUser = userInfoDao.getUserInfoById(Long.parseLong(hostUserId));
                UserAssignmentUtil.UserAssignment(hostUser, lineTimeRedisDao, userCallRedisDao);
                IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(hostUser.getIntegralSum());
                if (hostUser != null) {
                    if (hostUser.getIsLine() == 1) {
                        UserInfoDistanceDTO userInfoDistanceDTO = new UserInfoDistanceDTO();
                        userInfoDistanceDTO.setUserLevel(userIntegralLevel.getIntegralGrade());
                        userInfoDistanceDTO.setUserLevelPic(userIntegralLevel.getIntegralGradePic());
                        userInfoDistanceDTO.setUserLevelName(userIntegralLevel.getIntegralTitleName());
                        userInfoDistanceDTO.setIsHost(hostUser.getIsHost());
                        BeanUtils.copyProperties(hostUser, userInfoDistanceDTO);
                        userInfoDistanceDTO.setDistance("未知");
                        noDistanceUser.add(userInfoDistanceDTO);
                    }
                }
            }
            list.addAll(noDistanceUser);
        }

        return list;
    }

    public JSONObject getPhoneByUserId(long id) {
        String userName = userLoginDao.getPhoneByUserId(id);
        JSONObject jsonObject = new JSONObject();
        if (!StringUtils.isEmpty(userName)) {
            jsonObject.put("phone", userName);
        } else {
            jsonObject.put("phone", "");
        }
        return jsonObject;
    }

    public JSONObject getUserLevel(long userId) {
        JSONObject json = new JSONObject();
        User user = userInfoDao.getUserInfoById(userId);
        if (user == null)
            throw new IllegalParamException("用户不存在");
        EnergyLevel energyLevel = energyLevelService.getUserEnergyLevel(user.getEnergySum());
        json.put("icon", user.getIcon());
        json.put("userId", user.getUserId());
        json.put("nickName", user.getNickName());
        json.put("energySum", user.getEnergySum());
        json.put("energyGrade", energyLevel.getEnergyGrade());
        json.put("levelId", energyLevel.getLevelId());
        json.put("levelName", energyLevel.getLevelName());
        json.put("levelPic", energyLevel.getLevelPic());
        json.put("energyNextLevelValue", energyLevel.getUserEnergyNextLevelValue());
        return json;
    }

    public void updateUserNameByUserName(long id, String niceName) {
        if (SubstrUtil.length(niceName) > 16) {
            //    niceName = niceName.substring(0, 8);
            throw new ConsumeRuntimeException("最多填写8个汉字或16个字符");
        }
        User user = userInfoDao.getUserById(id);
        if (user != null) {
            if (user.getIsHost() == 2) {
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
                String time = simpleDateFormat.format(date);
                if (user.getIsVip() != 1 && user.getIsSvip()!=1 && user.getIsPlatinumVip()!=1) {
                    //判断普通用户是否修改过昵称
                    //修改过
                    if (userRedisDao.isUpdateNiceName(user.getUserId())) {
                        if (userRedisDao.getNiceNameNum(user.getUserId()).equals(appkeyService.getAppKeyByKey("userUpdateNum").getValue())) {
                            throw new ConsumeRuntimeException(UPDATE_USER_NICENAME);
                        } else {
                            int i = userInfoDao.updateNiceName(user.getUserId(), niceName);
                            userRedisDao.userInfoCheckNicName(user.getUserId());
                            if (i > 0) {
                                userRedisDao.addNiceNameNum(user.getUserId(), "1");
                                sendYunXinUpdateNiceName(id, niceName);
                            }
                        }
                        //没改过
                    } else {
                        int i = userInfoDao.updateNiceName(user.getUserId(), niceName);
                        userRedisDao.userInfoCheckNicName(user.getUserId());
                        if (i > 0) {
                            userRedisDao.addNiceNameNum(user.getUserId(), "1");
                            sendYunXinUpdateNiceName(id, niceName);
                        }
                    }
                } else if (user.getIsVip() == 1 || user.getIsSvip()==1 || user.getIsPlatinumVip()==1) {
                    if (!userRedisDao.isUpdateNiceName(user.getUserId())) {
                        int i = userInfoDao.updateNiceName(user.getUserId(), niceName);
                        userRedisDao.userInfoCheckNicName(user.getUserId());
                        if (i > 0) {
                            userRedisDao.addNiceNameNum(user.getUserId(), "1");
                            sendYunXinUpdateNiceName(id, niceName);
                        }
                    } else {
                        if (userRedisDao.getNiceNameNum(user.getUserId()).equals
                                (appkeyService.getAppKeyByKey("userUpdateNum").getValue())) {
                            if (userRedisDao.isUpdateVIPNiceName(user.getUserId(), time)) {
                                if (userRedisDao.getNiceNameVIPNum(user.getUserId(), time).
                                        equals(appkeyService.getAppKeyByKey("userVipUpdateNum").getValue())) {
                                    throw new ConsumeRuntimeException(UPDATE_VIP_USER_NICENAME);
                                } else {
                                    int i = userInfoDao.updateNiceName(user.getUserId(), niceName);
                                    userRedisDao.userInfoCheckNicName(user.getUserId());
                                    if (i > 0) {
                                        userRedisDao.addNiceNameVIPNum(user.getUserId(), time, "1");
                                        sendYunXinUpdateNiceName(id, niceName);
                                    }
                                }
                            } else {
                                int i = userInfoDao.updateNiceName(user.getUserId(), niceName);
                                userRedisDao.userInfoCheckNicName(user.getUserId());
                                if (i > 0) {
                                    userRedisDao.addNiceNameVIPNum(user.getUserId(), time, "1");
                                }
                            }
                        }
                    }
                }
            } else if (user.getIsHost() == 1) {
                userRedisDao.userInfoCheckNicNameForHost(user.getUserId(), niceName);
            }
        }
    }

//    /**
//     * 获取用户信息
//     * @param id
//     * @return
//     */
//    public JSONObject getUserByUserId(long tokenId,long userId) {
//        JSONObject json = new JSONObject();
//        User user = userInfoDao.getUserInfoById(userId);
//        if (user == null)
//            throw new IllegalParamException("用户不存在");
//        UserWallet userWallet = userWalletService.getUserWalletById(user.getUserId());
//        EnergyLevel energyLevel = energyLevelService.getUserEnergyLevel(user.getEnergySum());
//        System.out.println(energyLevel);
//        json.put("user",user);
//        json.put("userWallet",userWallet);
//        json.put("energyLevel",energyLevel);
//
//        return json;
//    }

    public void updateUserVehicleId(long userId, int vehicleId) {
        if (vehicleId < 1) {
            throw new ConsumeRuntimeException("vehicleId不存在");
        }
        User user = userInfoDao.getUserInfoById(userId);
        EnergyLevel energyLevel = energyLevelService.getUserEnergyLevel(user.getEnergySum());
        List<EnergyLevel> levelList = energyLevelDao.getLevelInfoList();
        for (EnergyLevel level : levelList) {
            if (level.getId() == vehicleId) {
                if (energyLevel.getEnergyGrade() >= level.getMinGrade()) {
                    userInfoDao.updateUserInfoVehicleId(userId, vehicleId);
                } else {
                    throw new ConsumeRuntimeException("用户等级未达到该等级");
                }
                break;
            }
        }
    }

    /**
     * 我的等级之主播信息
     *
     * @param id
     * @return
     */
    public JSONObject getHostUserLevel(long id) {
        JSONObject jsonObject = new JSONObject();
        User user = userInfoDao.getUserInfoById(id);
        if (user == null)
            throw new IllegalParamException("用户不存在");
        IntegralLevelAndTitleDTO userIntegralLevel = integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum());
        List<IntegralLevelAndTitleDTO> list = integralLevelInfoService.getList();
        List<UserPowerVo> powerVoList = new ArrayList<>();
        //去重
        Set<String> set = new HashSet<>();
        for (IntegralLevelAndTitleDTO integralLevelAndTitleDTO : list) {
            if (integralLevelAndTitleDTO.getIsTeaseUserRobot() == 1) {
                if (!set.contains("撩客机器人")) {
                    UserPowerVo userPowerVo = new UserPowerVo();
                    userPowerVo.setPowerName("撩客机器人");
                    userPowerVo.setIsOpen(userIntegralLevel.getIsTeaseUserRobot());
                    userPowerVo.setOpenLevel(integralLevelAndTitleDTO.getIntegralGrade());
                    powerVoList.add(userPowerVo);
                    set.add("撩客机器人");
                }

            }
            if (integralLevelAndTitleDTO.getIsTrenchFriendModule() == 1) {
                if (!set.contains("开放壕友模块")) {
                    UserPowerVo userPowerVo = new UserPowerVo();
                    userPowerVo.setPowerName("开放壕友模块");
                    userPowerVo.setIsOpen(userIntegralLevel.getIsTrenchFriendModule());
                    userPowerVo.setOpenLevel(integralLevelAndTitleDTO.getIntegralGrade());
                    powerVoList.add(userPowerVo);
                    set.add("开放壕友模块");
                }

            }
            if (integralLevelAndTitleDTO.getIsUserRechargeReminder() == 1) {
                if (!set.contains("用户充值提醒")) {
                    UserPowerVo userPowerVo = new UserPowerVo();
                    userPowerVo.setPowerName("用户充值提醒");
                    userPowerVo.setIsOpen(userIntegralLevel.getIsUserRechargeReminder());
                    userPowerVo.setOpenLevel(integralLevelAndTitleDTO.getIntegralGrade());
                    powerVoList.add(userPowerVo);
                    set.add("用户充值提醒");
                }

            }
            if (integralLevelAndTitleDTO.getIsModifyVoiceIntroduction() == 1) {
                if (!set.contains("修改语音介绍")) {
                    UserPowerVo userPowerVo = new UserPowerVo();
                    userPowerVo.setPowerName("修改语音介绍");
                    userPowerVo.setIsOpen(userIntegralLevel.getIsModifyVoiceIntroduction());
                    userPowerVo.setOpenLevel(integralLevelAndTitleDTO.getIntegralGrade());
                    powerVoList.add(userPowerVo);
                    set.add("修改语音介绍");
                }

            }
            if (integralLevelAndTitleDTO.getIsModifyLocation() == 1) {
                if (!set.contains("修改定位")) {
                    UserPowerVo userPowerVo = new UserPowerVo();
                    userPowerVo.setPowerName("修改定位");
                    userPowerVo.setIsOpen(userIntegralLevel.getIsModifyLocation());
                    userPowerVo.setOpenLevel(integralLevelAndTitleDTO.getIntegralGrade());
                    powerVoList.add(userPowerVo);
                    set.add("修改定位");
                }

            }
        }
        jsonObject.put("userIntegralLevel", userIntegralLevel);
        jsonObject.put("list", list);
        jsonObject.put("userPowerList", powerVoList);
        return jsonObject;
    }

    /**
     * 主播视频价格大于等级的视频价格时修改成当前等级的金币价格
     *
     * @param user
     * @param userIntegralLevel
     */
    public void updateUserVideoPrice(User user, IntegralLevelAndTitleDTO userIntegralLevel) {
        if (Integer.parseInt(user.getVideoPrice()) > userIntegralLevel.getGoldCoinsPerMinute()) {
            userInfoDao.updateVideoPrice(user.getUserId(), userIntegralLevel.getGoldCoinsPerMinute());
        }
    }

    /**
     * 更新主播实时位置
     *
     * @param location
     */
    public void updateHostRealTimeLocation(long userId, String location) throws Exception {
        User user = userInfoDao.getUserInfoById(userId);
        if (user.getIsHost() == 1) {
            LocationDTO locationDTO = new LocationDTO();

            locationDTO.setLat(location.split(",")[0]);
            locationDTO.setLon(location.split(",")[1]);

            LocationUtil.getProvinceAndCity(GaodeConfig.REGEO_URL, GaodeConfig.getKey(), locationDTO);
            if(locationDTO.getProvince().equals("北京市")
                    ||locationDTO.getProvince().equals("天津市")
                    ||locationDTO.getProvince().equals("上海市")||locationDTO.getProvince().equals("重庆市")){
                hostRealTimeLocationRedisDao.setAll(user.getUserId(),location,
                        locationDTO.getProvince(),
                        locationDTO.getProvince());
            }else {
                hostRealTimeLocationRedisDao.setAll(user.getUserId(),location,
                        locationDTO.getProvince(),
                        locationDTO.getCity());
            }


        }
    }

    /**
     * 获取主播最近动态
     * @param userId
     * @return
     */
    public Map<String,Object> getHostRecentDevelopmentsList(Long userId) throws IOException {
        Map<String,Object> map = new HashMap<>(2);
        //获取主播地址
        User user = userInfoDao.getUserInfoById(userId);
        String city = "保密";
        if(!StringUtils.isEmpty(user.getLocationCity())&&!user.getLocationCity().equals("[]")){
            city = user.getLocationCity();
        }else{
           String realCity= hostRealTimeLocationRedisDao.getProvince(userId);
           if(!StringUtils.isEmpty(realCity)&&!realCity.equals("[]")){
               city = realCity;
           }
        }

        map.put("city",city);

        List<Object> list =hostRecentDevelopmentsRedisDao.getList(userId);
        if(list.size()<3){
            int pageSize = 3 - list.size();
            List<UserCoverUrl> userCoverUrls = userCoverUrlDao.selectUserCoverUrlPage(userId, 0, pageSize);
            for(UserCoverUrl obj : userCoverUrls){
                HostRecentDevelopmentsPhotoVO vo = new HostRecentDevelopmentsPhotoVO();
                vo.setType(4);
                vo.setTitle("封面");
                vo.setPhotoUrl(obj.getCoverUrl());
                list.add(vo);
            }
        }
        map.put("list",list);
        return map;
    }

    public JSONObject getIsMemberFirstRechargeUser(long userId) {
        Boolean isMember = userRedisDao.isMemberFirstRechargeUser(userId);
        JSONObject json = new JSONObject();
        json.put("userId",userId);
        json.put("isFirstRecharge",!isMember);
        return json;
    }

    public JSONArray getHostIsLine(String hostUserIdArray) {
        JSONArray jsonArray = JSONArray.parseArray(hostUserIdArray);
        logger.info("getHostIsLine-jsonArray::::::"+jsonArray.toString());
        JSONArray returnJsonArray = new JSONArray();
        if(jsonArray.size()>0){
            jsonArray.forEach(i->{
                JSONObject json = new JSONObject();
                json.put("userId",i);
                User user = userInfoDao.getUserInfoById(Long.parseLong(i+""));
                getUserIsLine(user);
                json.put("isLine",user.getIsLine());
                returnJsonArray.add(json);
            });
        }
        return returnJsonArray;
    }

    public void getUserIsLine(User user){
        if(user.getIsHost()==1){
            //主播状态设置 0离线，1在线，2繁忙，3勿扰
            // 判断主播是否在线
            if (lineTimeRedisDao.isMember(user.getUserId() + ""))
                user.setIsLine(1);
            //如果用户为主播且正在通话中，则为繁忙状态
            if (user.getIsHost() == 1 && userCallRedisDao.findHostCall(user.getUserId() + ""))
                user.setIsLine(2);
            // 判断用户是否勿扰
            if (user.getIsVideo() == 2)
                user.setIsLine(3);
        }else {
            // 判断用户是否在线
            if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
                user.setIsLine(1);
            // 判断用户是否勿扰
            if (user.getIsVideo() == 2)
                user.setIsLine(3);
        }
    }


}
